const str: string = 'hello typescript!'

const num: number = 520

const bool: boolean = false

// 任意类型的数组
const arr1: any[] = [1, 2, 3, 4]

// 只能存储字符串的数组
const str_arr: string[] = ['1', '2', 'Job']

// number[]、boolean[]

// 任意类型的数组，写法2
const arr3: Array<any> = []

// 只能存储字符串的数组，写法2
const str_arr2: Array<string> = ['1', '2', 'Job']

// 元组
const location$: [number, number] = [25.33, 52.01]

// never类型
/**
 * never 类型表示那些永不存在的值的类型。它通常用于表示那些永远不会发生的情况
 */
// 因为这个函数永远不会返回
function infiniteLoop(): never {
    while (true) {
        // 无限循环
    }
}
// never 类型可以用于表示不可能存在的类型。例如，两个互斥类型的交集就是 never
type Impossible = string & number // 这个类型是 never，因为一个类型不可能是既是string又是number

// unknown 可以表示任何类型的值
/**
 * 与 any 类型不同，unknown 类型更加安全，因为它不允许你在没有类型检查的情况下直接使用其值
 * any 类型允许你在没有任何类型检查的情况下使用其值，这可能会导致类型错误和运行时错误。
 * unknown 类型要求你在使用其值之前进行类型检查或类型断言，从而提高了代码的安全性。
 */
function processValue(val: unknown): unknown {
    return val
}
processValue(1)
processValue('Mr.Zhu')
processValue(true)

const undef: undefined = undefined

const null_a: null = null

// 空类型, undefined位空类型可接受的一种
const void_a: void = undefined

// 对象类型
interface PersonInterface {
    name: string
    age: number
    gander: 'male' | 'female'
}

const person: PersonInterface = {
    name: 'Jack',
    age: 18,
    gander: 'male'
}

// 索引签名
interface SchoolInterface {
    name: string
    tel: string | number
    // 这是一个索引签名，表示对象可以有任意数量的其他属性，这些属性的键是 string 类型，值可以是任何类型（any）
    [key: string]: any
}

const school1: SchoolInterface = {
    name: '北京大学',
    tel: '010-12345678',
    // 拥有索引签名
    address: '北京市海淀区颐和园路5号',
    students: 30000
}

// 枚举
// 数字枚举
enum Season {
    Spring,
    Summer,
    Autumn,
    Winter
}
// 不指定值的话会默认从 0 开始 +1
console.log(Season.Spring) // 输出 0
console.log(Season.Summer) // 输出 1
console.log(Season.Autumn) // 输出 2
console.log(Season.Winter) // 输出 3

// 字符串枚举
enum SeasonTwo {
    Spring = '春',
    Summer = '夏',
    Autumn = '秋',
    Winter = '冬'
}
console.log(SeasonTwo.Spring) // 输出 春
console.log(SeasonTwo.Summer) // 输出 夏
console.log(SeasonTwo.Autumn) // 输出 秋
console.log(SeasonTwo.Winter) // 输出 冬

// 常量枚举
// 常量枚举（const enum）在编译时会被完全删除，只保留其值。这可以减少生成的 JavaScript 代码的大小。
const enum SeasonThree {
    Spring,
    Summer,
    Autumn,
    Winter
}

// 多种类型
const unite_a: string | number = 'Job'

type UniteTypeOne = string | number
type UniteTypeTwo = PersonInterface | Array<any>

const uniteOne: UniteTypeOne = 1314
const uniteTwo: UniteTypeTwo = [1, 'Lucy']

// 联合类型，为两种类型合在一起
type UniteTypeThree = { name: string } & { age: number } & {
    gander: 'male' | 'female'
}

const uniteThree: UniteTypeThree = {
    name: 'Miss.Liu',
    age: 18,
    gander: 'female'
}

// 合并
interface MergeInterface {
    status: 400 | 404 | 500
}

interface MergeInterface {
    state: 'success' | 'warn' | 'error' | 'info'
}
// 可以有重复名称的 interface， ts会自动进行合并
const merge: MergeInterface = {
    state: 'info',
    status: 400
}
